#ifndef GSETTINGS_H_
#define GSETTINGS_H_

#include <wx/wx.h>
#include <wx/propdlg.h>
#include <wx/generic/propdlg.h>
#include <wx/textctrl.h>
#include <vector>
#include "../../core/Impp.h"
#include "../../core/database/DBModule.h"
#include "../../core/settings/Settings.h"
#include "../../core/events/ImppCommandEvent.h"

namespace Impp
{

#define STD_SETTINGS_DIALOG_MODULE_NAME 			wxT("StdSettingsDialog")
#define STD_SETTINGS_DIALOG_MODULE_ACTION_SHOW		wxT("showSettingsDialog")

class GSetting{
public:
	int id;
	wxWindow* ctrl;
	Setting* setting;

	GSetting(const int & id,wxWindow* ctrl, Setting* setting) :
		id(id),ctrl(ctrl),setting(setting){};

	virtual bool processChanged() = 0;
};

class GTextSetting : public GSetting{
public:
	wxString value;

	GTextSetting(const int & id, wxTextCtrl* ctrl,const wxString & defaultValue, Setting* setting) :
		GSetting(id,ctrl,setting),value(defaultValue) {};

	virtual bool processChanged(){
		wxTextCtrl* txtCtrl = static_cast<wxTextCtrl*>(ctrl);
		if(value != txtCtrl->GetValue()){
			wxCommandEvent event = wxCommandEvent(wxEVT_COMMAND_TEXT_ENTER,id);
			event.SetString(txtCtrl->GetValue());
			Impp::exemplar()->AddPendingEvent(event);
			//wxLogDebug(wxT("event sent"));
			return true;
		}
		return false;
	};
};

struct OptionPair{
	wxString displayName;
	wxString value;

	OptionPair(wxString displayName, wxString value) :
		displayName(displayName),value(value){};

	OptionPair(){};
};

class GCheckSetting : public GSetting{
public:
	bool wasChecked;

	GCheckSetting(const int & id, wxCheckBox* ctrl, bool  defaultValue, Setting* setting) :
		GSetting(id,ctrl,setting),wasChecked(defaultValue){};

		virtual bool processChanged(){
			wxCheckBox* checkCtrl = static_cast<wxCheckBox*>(ctrl);
			if(wasChecked != checkCtrl->IsChecked()){
				wxCommandEvent event = wxCommandEvent(wxEVT_COMMAND_MENU_SELECTED,id);
				event.SetInt(checkCtrl->IsChecked());
				Impp::exemplar()->AddPendingEvent(event);

				if(setting != NULL){
					Impp::exemplar()->processSettingChangedInt(setting->getModule(),setting->getSettingName(), checkCtrl->IsChecked());
				}
				return true;
			}
			return false;
		};
};

class GOptionsSetting : public GSetting{
public:
	OptionPair* options;
	int count;
	int defaultv;

	GOptionsSetting(const int & id, wxComboBox* ctrl,int defaultv, OptionPair* options, int count, Setting* setting) :
		GSetting(id,ctrl, setting),options(options),count(count) {};


	virtual bool processChanged(){
		wxComboBox* comboCtrl = static_cast<wxComboBox*>(ctrl);
		if(defaultv != comboCtrl->GetSelection()){
			wxCommandEvent event = wxCommandEvent(wxEVT_COMMAND_MENU_SELECTED,id);
			event.SetString(options[comboCtrl->GetSelection()].value);
			Impp::exemplar()->AddPendingEvent(event);
			//wxLogDebug(wxT("event sent"));
			if(setting != NULL){
				Impp::exemplar()->processSettingChangedString(setting->getModule(),setting->getSettingName(), options[comboCtrl->GetSelection()].value);
			}
			return true;
		}
		return false;
	};

	~GOptionsSetting(){
		delete[] options;
	}
};

// Property sheet dialog
class SettingsDialog: public wxPropertySheetDialog
{

DECLARE_CLASS(SettingsDialog)
private:
	 std::vector<GSetting*> settings;
	 wxTextCtrl* txtScreenName;
	 wxTextCtrl* txtPW;

public:
    SettingsDialog(wxWindow* parent);
    ~SettingsDialog();

    wxPanel* CreateOscarSettingsPage(wxWindow* parent);
    wxPanel* CreatePageBySettingsPage(wxWindow* parent, SettingsPage* sPage);

    wxBoxSizer* createSettingsGroup(wxWindow* parent, const wxString & label);
    wxSizer* createTextPreference(wxWindow* parent,const wxString & label,const DBModule & dbModule,const wxString & dbValue, const int & id, const long & flags = 0);
    wxCheckBox* createCheckPreference(wxWindow* parent,const wxString & label,const DBModule & dbModule,const wxString & dbValue, const int & id, const long & flags = 0);
    wxCheckBox* createCheckPreference(wxWindow* parent,CheckSetting* setting, const int & id, const long & flags = 0);
    wxComboBox* createOptionPreference(wxWindow* parent,const wxString & label,const DBModule & dbModule,const wxString & dbValue,const OptionPair* options, const int & optionsCount, const int & id, const long & flags = wxCB_READONLY);
    wxComboBox* createOptionPreference(wxWindow* parent, ChooseSetting* setting, const int & id, const long & flags = wxCB_READONLY);

    void onOk(wxCommandEvent & event);


protected:
    wxImageList*    m_imageList;

    DECLARE_EVENT_TABLE()
};


class StdSettingsDialogModule : public iModule{

	DECLARE_DYNAMIC_CLASS(StdSettingsDialogModule)

public:
	StdSettingsDialogModule(){};
	virtual ~StdSettingsDialogModule(){};

	void moduleInit();
	void moduleDestroy(){};

	static void wxCALLBACK addMainMenuItem(iMenu* menu, void* ptr);
	void onImppCommand(ImppCommandEvent & event);

};


}

#endif /*SETTINGS_H_*/
